/*
This class use to load all the resource file. 
All the resource must list in "resmap.xml" file(script, textures, sounds etc).
If the format about the file "resmap.xml" is error by this engine, 
the error message will raise and the program will soon quit.
*/
#include "Resource.h"

ModelLoaderMid::ModelLoaderMid(void)
:Component("ModelLoaderMid")
{
}

ModelLoaderMid::~ModelLoaderMid()
{
}

void ModelLoaderMid::addedToObject(void)
{
    requestMessage("ModelPoly",&ModelLoaderMid::PolyModel);
}

void ModelLoaderMid::PolyModel(const Message &msg)
{
    LOAD_MSG;
    string filename=boost::any_cast<string>(*iter);
    if(filename.find(".m2"))
    {
        sendMessage("LoadWOWModel",msg.p);
    }

}

Resource::Resource(void)
:Component("Resource"),
m_pscrRoot(0),
m_prmRoot(0),
m_curNode(NULL)
{
}

Resource::~Resource(void)
{
}

void Resource::addedToObject()
{
    requestMessage("LoadSysMenu",&Resource::LoadSysMenu);
    requestMessage("LoadFightMenu",&Resource::LoadFightMenu);
    requestMessage("LoadFigure",&Resource::LoadFigure);
    requestMessage("NextScene",&Resource::NextScene);
    requestMessage("Init",&Resource::Init);
    requestMessage("LoadMap",&Resource::LoadMap);
    requestMessage("InitFight",&Resource::LoadFightRes);
}

void Resource::Init(const Message &msg)
{
    if(!LoadRes())
    {
        SEND_ERR_MSG("Init Error");
    }
    LogicEngine* le=(LogicEngine*)msg.sender;
    le->ChangeGameState(LoadSceneState());
    ModelLoaderMid* mlMid=new ModelLoaderMid;
	addLocalComponent(mlMid);
    WoWLoader* wl=new WoWLoader;
    ObjectId wId=createObject();
	addComponent(wId,wl);
}

void Resource::NextScene(const Message& msg)
{
    assert(m_curNode);
    m_curNode=m_curNode->NextSiblingElement();
    if(m_curNode==NULL)
        SEND_ERR_MSG("Next scene error!");
    LogicEngine* le=(LogicEngine*)msg.sender;
    le->ChangeGameState(LoadSceneState());
}

GAME_STATE Resource::LoadSceneState()
{
    const char* state=m_curNode->Attribute("state");
    if(state==NULL)
    {
        ::MessageBox(NULL,"LoadSceneState Failed!","Error",MB_OK);
        return END;
    }
    if(strcmp("story",state)==0)
    {
        return STORY;
    }
    else if(strcmp("fight",state)==0)
    {
        return FIGHT;
    }
    else
    {
        return END;
    }
}

void Resource::LoadFigure(const Message &msg)
{
    LoadModel();
    LoadFigureInfo();
}

void Resource::LoadModel()
{
    TiXmlElement* model=m_pscrRoot.FirstChild("MODEL").FirstChildElement().Element();
    if(model==NULL)
        SEND_ERR_MSG("Element <MODEL> can not found in xml file!");
    do
    {
        string fname("./Res/Model/");
        string mname;
        mname.append(model->Attribute("name"));
        fname.append(mname);
        fname.append("/");
        fname.append(mname);
        fname.append(".m2");
        assert(!fname.empty());
        vector<boost::any> any;
        any.push_back(fname);
        sendLocalMessage("ModelPoly",any);
        vector<boost::any> any_1;
        any_1.push_back(mname);
        sendMessage("AddModel",any_1);
    }
    while(model=model->NextSiblingElement());
}

void Resource::LoadFigureInfo()
{
    TiXmlElement* pos=m_pscrRoot.FirstChild("FIGURE").FirstChildElement().Element();
    if(pos==NULL)
        SEND_ERR_MSG("Element <FIGURE> not found!");
    do
    {
        FIGURE_ABILITY fa;
        memset(&fa,0,sizeof(FIGURE_ABILITY));
        int32 mid=-1,face;
        string fname;
        string mname;
        int32 x=0,y=0;
        fname.append(pos->Attribute("name"));
        mname.append(pos->Attribute("model_name"));
        vector<boost::any> any;
        any.push_back(mname);
        any.push_back(&mid);
        sendMessage("FindModel",any);
        if(mid==-1)
        {
            SEND_ERR_MSG("Model not found.");
        }
        pos->Attribute("x",&x);
        pos->Attribute("y",&y);
        pos->Attribute("face",&face);
        TiXmlElement* atx=pos->FirstChildElement("ATTRIBUTE");
        if(atx!=NULL)
        {
            fa.hp=atoi(atx->FirstChildElement("HP")->GetText());
            fa.mp=atoi(atx->FirstChildElement("MP")->GetText());
            fa.move=atoi(atx->FirstChildElement("MOVE")->GetText());
        }
        vector<boost::any> any_1;
        any_1.push_back(fname);
        any_1.push_back(mid);
        any_1.push_back(x);
        any_1.push_back(y);
        any_1.push_back(face);
        any_1.push_back(fa);
        sendMessage("AddFigure",any_1);
    }
    while(pos=pos->NextSiblingElement());
}

void Resource::LoadMap(const Message & msg)
{
    /*World* w=(World*)msg.sender;
    TiXmlElement* map=m_pscrRoot.FirstChildElement("MAP").Element();
    if(map==NULL)
    SEND_ERR_MSG("Element <MAP> not found!");
    TiXmlElement* world=map->FirstChildElement("WORLD");
    if(world==NULL)
    SEND_ERR_MSG("Element <WORLD> not found!");
    int32 x=0,y=0;
    world->Attribute("maxW",&x);
    world->Attribute("maxH",&y);
    world=map->FirstChildElement("TEX");
    if(world==NULL)
    SEND_ERR_MSG("Element <TEX> not found!");
    char fname[256]="./Res/World/";
    strcat_s(fname,256,world->Attribute("ext"));
    w->LoadGround(x,y,fname);*/
}

void Resource::LoadFightRes(const Message &msg)
{
    char filename[256]="./Res/XML/";
    const char* state = m_curNode->Attribute("state");
    if(state==NULL)
        SEND_ERR_MSG("Attribute \"state\" not found!");
    if(strcmp(state,"fight")!=0)
        SEND_ERR_MSG("Fight xml file format error!");
    strcat_s(filename,256,m_curNode->Attribute("ext"));
    if(filename==NULL)
        SEND_ERR_MSG("Attribute \"ext\" not found!");
    if(!m_scrdoc.LoadFile(filename))
        SEND_ERR_MSG("Can not found sub fight xml file!");
    m_pscrRoot=TiXmlHandle(&m_scrdoc);
    m_pscrRoot=m_pscrRoot.FirstChildElement();
}

bool Resource::LoadRes()
{
    if (!m_rmdoc.LoadFile(RES_MAP))
    {
        return false;
    }
    m_prmRoot=TiXmlHandle(&m_rmdoc);
    m_prmRoot=m_prmRoot.FirstChild("STL");
    if(m_prmRoot.Node()==NULL)
        return false;
    m_curNode=m_prmRoot.FirstChild("SCENE").Element();
    if(m_curNode==NULL)
        return false;
    return true;
}

void Resource::LoadSysMenu(const Message &msg)
{		
    /*ScreenWorld* sw=(ScreenWorld*)msg.sender;
    int32 id=-1;
    TiXmlElement* xe=m_prmRoot.FirstChild("SYSTEM_RES").FirstChild().Element();
    if(xe==NULL)
    SEND_ERR_MSG("Element <SYSTEM_RES> not found!");
    do
    {
    char fname[256]="./Res/Menu/System/";
    xe->Attribute("id",&id);
    strcat_s(fname,256,xe->Attribute("ext"));
    if(!sw->AddSysMenu(id,fname))
    SEND_ERR_MSG("Load system menu error!");
    }
    while(xe=xe->NextSiblingElement());*/
}

void Resource::LoadFightMenu(const Message & msg)
{
    /*ScreenWorld* sw=(ScreenWorld*)msg.sender;
    int32 id=-1;
    TiXmlElement* xe=m_prmRoot.FirstChild("FIGHT_RES").FirstChild().Element();
    if(xe==NULL)
    SEND_ERR_MSG("Element <FIGHT_RES> not found!");
    do
    {
    char fname[256]="./Res/Menu/Fight/";
    xe->Attribute("id",&id);
    strcat_s(fname,256,xe->Attribute("ext"));
    if(!sw->AddFightMenu(id,fname))
    SEND_ERR_MSG("Load fight menu error!");
    }
    while(xe=xe->NextSiblingElement());*/
}


/*BOOL Resource::LoadTexture(TiXmlElement* xe)
{
TiXmlElement* group=xe->FirstChildElement();
if(group==NULL)
return FALSE;

do
{
const char* kind = group->Value();
TiXmlElement* se=group->FirstChildElement();
if(se==NULL)
return FALSE;
do
{
int id=0;
int state=0;

TiXmlAttribute* at=se->FirstAttribute();
if(at)
{
do
{
if(strcmp(at->Name(),"ID")==0)
{
id=atoi(at->Value());
}
else if(strcmp(at->Name(),"State")==0)
{
state=atoi(at->Value());
}
}while(at=at->Next());
}
const char* filename=se->GetText();
if(!g_tex.AddTexture(filename,kind,id,state))
g_err.SendErrorMessage(ERR_FUNC,"Texture::AddTexture");
}
while(se=se->NextSiblingElement());
}
while(group=group->NextSiblingElement());
return TRUE;
}*/

/*BOOL Resource::LoadSound(TiXmlElement* xe)
{
return TRUE;
}*/

/*bool Resource::LoadScript(const char* file)
{
if (!m_scrdoc.LoadFile(file)) 
return FALSE;
m_pscrRoot=TiXmlHandle(&m_scrdoc);
m_pscrRoot=m_pscrRoot.FirstChild("STL");
if((m_pscrNode=m_pscrRoot.FirstChild().ToElement())==NULL)
{
//g_err.SendErrorMessage(ERR_FILE,"Script.xml");
}
return true;
}*/